/*
* Copyright (C) 2014 IUH �yber$oft Team
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package vn.cybersoft.obs.android.fragments;
import java.lang.ref.WeakReference;
import java.util.Calendar;
import java.util.List;
import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import vn.cybersoft.obs.android.R;
import vn.cybersoft.obs.android.activities.CleanerActivity;
import vn.cybersoft.obs.android.models.BatteryInfo;
import vn.cybersoft.obs.android.provider.BatteryTrace;
import vn.cybersoft.obs.android.utilities.DeviceUtils;
import vn.cybersoft.obs.android.utilities.Log;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
/**
* @author Luan Vu
*
*/
public class BatteryInfoFragment extends Fragment {
private static final String t = BatteryInfoFragment.class.getSimpleName();
public static final int LAYOUT_ID = R.layout.battery_info_fragment;
private static final int LIMIT_DATE_SHOW = 2;
private static final int MINIMUM_VALUE_TO_SHOW_CHART = 4;
private IncomeinHandler mHandler = new IncomeinHandler(this);
private BatteryInfo mBatteryInfo;
private BatteryInfoReceiver mBatteryInfoReceiver;
private TextView mTemperature, mVoltage, mCapacity, mTimeLeftHour, mTimeLeftMin, mBatteryLevel;
private TextView mTimeLeftText;
private ImageView mBatteryImg;
private Button mCleanApp;
private ViewGroup mUsageChart;
private XYMultipleSeriesDataset mDataset;
private XYMultipleSeriesRenderer mRenderer;
private GraphicalView mChartView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(getString(R.string.app_name) + " > " + getString(R.string.battery_info));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(LAYOUT_ID, container, false);
mTimeLeftText = (TextView) view.findViewById(R.id.time_left);
mTimeLeftHour = (TextView) view.findViewById(R.id.time_left_hour);
mTimeLeftMin = (TextView) view.findViewById(R.id.time_left_minutes);
mTemperature = (TextView) view.findViewById(R.id.temperature_text);
mVoltage = (TextView) view.findViewById(R.id.voltage_text);
mBatteryLevel = (TextView) view.findViewById(R.id.battery_level_text);
mBatteryImg = (ImageView) view.findViewById(R.id.battery_img);
mCapacity = (TextView) view.findViewById(R.id.capacity_text);
mCapacity.setText(getBatteryCapacity()+ "");
mBatteryInfo = new BatteryInfo();
mBatteryInfoReceiver = new BatteryInfoReceiver();
mCleanApp = (Button) view.findViewById(R.id.cleanUpButton);
mCleanApp.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
cleanApp();
}
});
drawChart();
mUsageChart = (ViewGroup) view.findViewById(R.id.battery_usage_chart);
if (mChartView != null) {
mUsageChart.addView(mChartView, 0);
} else {
mUsageChart.findViewById(R.id.empty_usage).setVisibility(View.VISIBLE);
}
return view;
}
private void cleanApp() {
new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.clean_up))
.setMessage(getString(R.string.clean_up_confirm))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int w) {
Intent i = new Intent(getActivity(), CleanerActivity.class);
startActivity(i);
}
}).show();
}
private void drawChart() {
mRenderer = new XYMultipleSeriesRenderer();
mDataset = new XYMultipleSeriesDataset();
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setLineWidth(5);
renderer.setColor(Color.parseColor("#0099cc"));
renderer.setDisplayBoundingPoints(true);
renderer.setPointStyle(PointStyle.CIRCLE);
renderer.setPointStrokeWidth(10);
//FillOutsideLine fillOutsideLine = new FillOutsideLine(Type.BOUNDS_ALL);
//fillOutsideLine.setColor(Color.parseColor("#0099cc"));
//renderer.addFillOutsideLine(fillOutsideLine);
//mRenderer.setChartTitle("Battery Level (%)");
mRenderer.setChartTitleTextSize(30f);
mRenderer.setLabelsTextSize(20f);
mRenderer.addSeriesRenderer(renderer);
mRenderer.setMarginsColor(Color.argb(0x00, 0xff, 0x00, 0x00));
mRenderer.setPanEnabled(true, false);
mRenderer.setZoomEnabled(false, false);
mRenderer.setYAxisMax(DeviceUtils.getBatteryScale(getActivity()));
mRenderer.setYAxisMin(0);
//mRenderer.setShowGrid(true);
mRenderer.setGridColor(Color.GRAY);
mRenderer.setClickEnabled(false);
TimeSeries series = new TimeSeries("");
/* long value = new Date().getTime() - 3 * TimeChart.DAY;
for (int i = 0; i < 5; i++) {
series.add(new Date(value + i * TimeChart.DAY / 4), i);
}*/
List<BatteryTrace> traces = BatteryTrace.getClosestTraceData(getActivity().getContentResolver(), LIMIT_DATE_SHOW);
boolean chartVisible = traces.size() >= MINIMUM_VALUE_TO_SHOW_CHART;
if (chartVisible) {
Calendar panMinimumX = Calendar.getInstance();
panMinimumX.set(Calendar.HOUR_OF_DAY, traces.get(0).hour);
panMinimumX.set(Calendar.MINUTE, traces.get(0).minutes);
Calendar panMaximumX = Calendar.getInstance();
panMaximumX.set(Calendar.HOUR_OF_DAY, traces.get(traces.size()-1).hour);
panMaximumX.set(Calendar.MINUTE, traces.get(traces.size()-1).minutes);
//mRenderer.setPanLimits(new double[] {panMinimumX.getTimeInMillis(), panMaximumX.getTimeInMillis() * 2, 0, 0});
for (BatteryTrace b : traces) {
//System.out.println(b.toString());
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, b.hour);
c.set(Calendar.MINUTE, b.minutes);
series.add(c.getTime(), b.level);
}
mDataset.addSeries(series);
mChartView = ChartFactory.getTimeChartView(getActivity(), mDataset, mRenderer, "hh:mm aa");
}
}
@Override
public void onStart() {
super.onStart();
Log.v(t + ".onStart()");
}
@Override
public void onResume() {
super.onResume();
Log.v(t + ".onResume()");
getActivity().registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
@Override
public void onPause() {
super.onPause();
Log.v(t + ".onPause()");
getActivity().unregisterReceiver(mBatteryInfoReceiver);
}
@Override
public void onStop() {
super.onStop();
Log.v(t + ".onStop()");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.v(t + ".onDestroyView()");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.v(t + ".onDestroy()");
}
private void updateLayout() {
mTemperature.setText((float)mBatteryInfo.temperature / 10 + "");
mVoltage.setText((float)mBatteryInfo.voltage / 1000 + "");
int batteryPercentage = mBatteryInfo.getBatteryPercentage();
boolean isCharging = mBatteryInfo.status == BatteryManager.BATTERY_STATUS_CHARGING;
mBatteryLevel.setText(batteryPercentage + "%");
if (isCharging) {
mTimeLeftText.setText(getString(R.string.charging_time_left));
if (batteryPercentage <= 10) {
mBatteryImg.setImageResource(R.drawable.psac0);
} else if(batteryPercentage <= 25) {
mBatteryImg.setImageResource(R.drawable.psac1);
} else if(batteryPercentage <= 50) {
mBatteryImg.setImageResource(R.drawable.psac2);
} else if(batteryPercentage <= 75) {
mBatteryImg.setImageResource(R.drawable.psac3);
} else {
mBatteryImg.setImageResource(R.drawable.psac4);
}
} else {
mTimeLeftText.setText(getString(R.string.time_left));
if(batteryPercentage <= 10) {
mBatteryImg.setImageResource(R.drawable.p1);
} else if(batteryPercentage <= 25) {
mBatteryImg.setImageResource(R.drawable.p2);
} else if(batteryPercentage <= 50) {
mBatteryImg.setImageResource(R.drawable.p3);
} else if(batteryPercentage <= 75) {
mBatteryImg.setImageResource(R.drawable.p4);
} else {
mBatteryImg.setImageResource(R.drawable.p5);
}
}
}
private class BatteryInfoReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Log.LOGV) {
Log.v(t + ".BatteryInfoReceiver.onReceive()");
}
mBatteryInfo.status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_UNKNOWN);
mBatteryInfo.heath = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN);
mBatteryInfo.present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
mBatteryInfo.level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
mBatteryInfo.scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
mBatteryInfo.iconSmall = intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL, 0);
mBatteryInfo.plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
mBatteryInfo.voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
mBatteryInfo.temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
mBatteryInfo.technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
mBatteryInfo.invalidCharger = intent.getIntExtra("invalid_charger", 0);
mHandler.sendEmptyMessage(0);
}
}
/*
* Used to prevent memory leaks
*/
static class IncomeinHandler extends Handler {
private final WeakReference<BatteryInfoFragment> mTarget;
IncomeinHandler(BatteryInfoFragment target) {
mTarget = new WeakReference<BatteryInfoFragment>(target);
}
@Override
public void handleMessage(Message msg) {
BatteryInfoFragment target = mTarget.get();
if (target != null) {
target.updateLayout();
}
}
}
private double getBatteryCapacity() {
Object powerProfile = null;
final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";
try {
powerProfile = Class.forName(POWER_PROFILE_CLASS)
.getConstructor(android.content.Context.class).newInstance(getActivity());
} catch (Exception e) {
e.printStackTrace();
}
double ret = 0;
try {
ret = (Double) Class.forName(POWER_PROFILE_CLASS)
.getMethod("getBatteryCapacity")
.invoke(powerProfile);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}